﻿using System;
using System.Windows.Forms;

namespace OSController
{
    internal class Controller
    {
        public Controller(Form form)
        {
            this.form = form;
        }

        private Form form { get; set; }
        public ActionType Action { get; set; }

        public void Lock()
        {
            Importer.LockWorkStation();
        }

        public void TurnOffMonitor()
        {
            Importer.SendMessage(form.Handle, Constants.WM_SYSCOMMAND, Constants.SC_MONITORPOWER, Constants.MONITOR_OFF);
        }

        private void DoExitWin(int flg)
        {
            Importer.TokPriv1Luid tp;
            IntPtr hproc = Importer.GetCurrentProcess();
            IntPtr htok = IntPtr.Zero;
            Importer.OpenProcessToken(hproc, Constants.TOKEN_ADJUST_PRIVILEGES | Constants.TOKEN_QUERY, ref htok);
            tp.Count = 1;
            tp.Luid = 0;
            tp.Attr = Constants.SE_PRIVILEGE_ENABLED;
            Importer.LookupPrivilegeValue(null, Constants.SE_SHUTDOWN_NAME, ref tp.Luid);
            Importer.AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            Importer.ExitWindowsEx(flg, 0);
        }

        public void LogOff()
        {
            DoExitWin(Constants.EWX_LOGOFF);
        }

        public void Sleep()
        {
            Importer.SetSuspendState(false, true, true);
        }

        public void Hibernate()
        {
            Importer.SetSuspendState(true, true, true);
        }

        public void ShutDown()
        {
            DoExitWin(Constants.EWX_SHUTDOWN);
        }

        public void Restart()
        {
            DoExitWin(Constants.EWX_REBOOT);
        }

        public void ApplyAction()
        {
            ApplyAction(Action);
        }

        public void ApplyAction(ActionType action)
        {
            switch (action)
            {
                case ActionType.MonitorOff:
                    TurnOffMonitor();
                    break;
                case ActionType.Lock:
                    Lock();
                    break;
                case ActionType.LogOff:
                    LogOff();
                    break;
                case ActionType.Sleep:
                    Sleep();
                    break;
                case ActionType.Hibernate:
                    Hibernate();
                    break;
                case ActionType.Restart:
                    Restart();
                    break;
                case ActionType.ShutDown:
                    ShutDown();
                    break;
            }
        }
    }

    internal enum ActionType
    {
        MonitorOff,
        Lock,
        LogOff,
        Sleep,
        Hibernate,
        Restart,
        ShutDown
    }
}